Õppige looma kohandatud erindihierarhiaid Pythonis. See juhend aitab ehitada robustsemaid, hooldatavamaid ja informatiivsemaid rakendusi.
Pythoni erinditöötlus: Kohandatud erindihierarhiate loomine robustsete rakenduste jaoks
Erinditöötlus on robustse ja hooldatava Pythoni koodi kirjutamisel ülioluline aspekt. Kuigi Pythoni sisseehitatud erandid pakuvad tugeva aluse, võimaldab kohandatud erindihierarhiate loomine kohandada veatöötlust vastavalt teie rakenduse spetsiifilistele vajadustele. See artikkel uurib kohandatud erindihierarhiate loomise eeliseid ja parimaid praktikaid Pythonis, andes teile võimaluse luua vastupidavamat ja informatiivsemat tarkvara.
Miks luua kohandatud erindihierarhiaid?
Kohandatud erindite kasutamine pakub mitmeid eeliseid võrreldes ainult sisseehitatud erandite kasutamisega:
- Parem koodi selgus: Kohandatud erandid annavad selgelt märku teie rakenduse domeenis esinevatest spetsiifilistest veaolukordadest. Need edastavad vigade kavatsust ja tähendust tõhusamalt kui üldised erandid.
- Parem hooldatavus: Hästi defineeritud erindihierarhia muudab veatöötlusloogika mõistmise ja muutmise lihtsamaks, kui teie rakendus areneb. See pakub struktureeritud lähenemist vigade haldamisele ja vähendab koodi dubleerimist.
- Detailne veatöötlus: Kohandatud erandid võimaldavad teil püüda ja käsitleda spetsiifilisi veatüüpe erinevalt. See võimaldab täpsemat vigadest taastumist ja aruandlust, mis viib parema kasutajakogemuseni. Näiteks võiksite proovida toimingut uuesti, kui ilmneb `NetworkError`, kuid lõpetada kohe, kui tekitatakse `ConfigurationError`.
- Domeenispetsiifiline veainfo: Kohandatud erandid võivad kanda lisateavet vea kohta, näiteks veakoode, asjakohaseid andmeid või kontekstipõhiseid detaile. See teave võib olla silumisel ja tõrkeotsingul hindamatu.
- Testitavus: Kohandatud erindite kasutamine lihtsustab ühiktestimist, võimaldades teil hõlpsasti väita, et teatud tingimustel tekitatakse spetsiifilisi vigu.
Oma erindihierarhia kujundamine
Tõhusa kohandatud erinditöötluse võti peitub hästi kujundatud erindihierarhia loomises. Siin on samm-sammuline juhend:
1. Määratlege baaserindiklass
Alustage oma rakenduse või mooduli jaoks baaserindiklassi loomisest. See klass on teie kohandatud erindihierarhia juur. Hea tava on pärineda Pythoni sisseehitatud `Exception` klassist (või mõnest selle alamklassist, näiteks `ValueError` või `TypeError`, kui see on asjakohane).
Näide:
class MyAppError(Exception):
"""MyAppi kõigi erandite baasklass."""
pass
2. Tuvastage veakategooriad
Analüüsige oma rakendust ja tuvastage peamised veakategooriad, mis võivad tekkida. Need kategooriad moodustavad teie erindihierarhia harud. Näiteks e-kaubanduse rakenduses võivad teil olla sellised kategooriad nagu:
- Autentimisvead: Vead, mis on seotud kasutaja sisselogimise ja autoriseerimisega.
- Andmebaasi vead: Vead, mis on seotud andmebaasi ühenduse, päringute ja andmete terviklikkusega.
- Võrguvead: Vead, mis on seotud võrguühenduse ja kaugteenustega.
- Sisendi valideerimisvead: Vead, mis on seotud kehtetu või valesti vormindatud kasutajasisendiga.
- Maksetöötluse vead: Vead, mis on seotud makselüüsi integratsiooniga.
3. Looge spetsiifilised erindiklassid
Iga veakategooria jaoks looge spetsiifilised erindiklassid, mis esindavad üksikuid veaolukordi. Need klassid peaksid pärinema vastavast kategooria erindiklassist (või otse teie baaserindiklassist, kui detailsem hierarhia pole vajalik).
Näide (Autentimisvead):
class AuthenticationError(MyAppError):
"""Autentimisvigade baasklass."""
pass
class InvalidCredentialsError(AuthenticationError):
"""Tekitatakse, kui esitatud mandaadid on kehtetud."""
pass
class AccountLockedError(AuthenticationError):
"""Tekitatakse, kui kasutajakonto on lukustatud."""
pass
class PermissionDeniedError(AuthenticationError):
"""Tekitatakse, kui kasutajal pole piisavaid õigusi."""
pass
Näide (Andmebaasi vead):
class DatabaseError(MyAppError):
"""Andmebaasivigade baasklass."""
pass
class ConnectionError(DatabaseError):
"""Tekitatakse, kui andmebaasiĂĽhendust ei saa luua."""
pass
class QueryError(DatabaseError):
"""Tekitatakse, kui andmebaasipäring ebaõnnestub."""
pass
class DataIntegrityError(DatabaseError):
"""Tekitatakse, kui andmete terviklikkuse piirangut on rikutud."""
pass
4. Lisage kontekstuaalset teavet
Täiustage oma erindiklasse, lisades atribuute vea kohta kontekstuaalse teabe salvestamiseks. See teave võib olla silumisel ja logimisel uskumatult väärtuslik.
Näide:
class InvalidCredentialsError(AuthenticationError):
def __init__(self, username, message="Vigane kasutajanimi või parool."):
super().__init__(message)
self.username = username
Nüüd, seda erandit tekitades, saate anda kasutajanime, mis vea põhjustas:
raise InvalidCredentialsError(username="testuser")
5. Implementeerige
__str__
meetod
Alistage oma erindiklassides
__str__
meetod, et pakkuda vea kasutajasõbralikku tekstiesitust. See muudab vea mõistmise lihtsamaks, kui see prinditakse või logitakse.
Näide:
class InvalidCredentialsError(AuthenticationError):
def __init__(self, username, message="Vigane kasutajanimi või parool."):
super().__init__(message)
self.username = username
def __str__(self):
return f"InvalidCredentialsError: {self.message} (Kasutajanimi: {self.username})"
Kohandatud erindite kasutamise parimad praktikad
Kohandatud erinditöötluse eeliste maksimeerimiseks järgige neid parimaid praktikaid:
- Olge spetsiifiline: Tekitage võimalikult spetsiifiline erand, et veaolukorda täpselt esindada. Vältige üldiste erandite tekitamist, kui saadaval on spetsiifilisemad.
- Ärge püüdke liiga laialt: Püüdke ainult neid erandeid, mida ootate ja oskate käsitleda. Laiade erandiklasside (nagu `Exception` või `BaseException`) püüdmine võib varjata ootamatuid vigu ja muuta silumise keerulisemaks.
- Tekitage erandeid uuesti hoolikalt: Kui püüate erandi kinni ja ei suuda seda täielikult käsitleda, tekitage see uuesti (kasutades `raise`), et kõrgema taseme käsitleja saaks sellega tegeleda. Samuti võite algse erandi mähkida uude, spetsiifilisemasse erandisse, et pakkuda lisakonteksti.
- Kasutage `finally` plokke: Kasutage `finally` plokke, et tagada puhastuskoodi (nt failide sulgemine, ressursside vabastamine) alati täitmine, olenemata sellest, kas erand tekib või mitte.
- Logige erandeid: Logige erandeid piisavalt üksikasjalikult, et aidata silumisel ja tõrkeotsingul. Kaasake erandi tüüp, sõnum, traceback ja mis tahes asjakohane kontekstuaalne teave.
- Dokumenteerige oma erandid: Dokumenteerige oma kohandatud erindihierarhia oma koodi dokumentatsioonis. Selgitage iga erindiklassi eesmärki ja tingimusi, mille korral see tekitatakse.
Näide: Failitöötlusrakendus
Vaatleme lihtsustatud näidet failitöötlusrakendusest, mis loeb ja töötleb andmeid CSV-failidest. Saame luua kohandatud erindihierarhia erinevate failiga seotud vigade käsitlemiseks.
class FileProcessingError(Exception):
"""Failitöötlusvigade baasklass."""
pass
class FileNotFoundError(FileProcessingError):
"""Tekitatakse, kui faili ei leita."""
def __init__(self, filename, message=None):
if message is None:
message = f"Faili ei leitud: {filename}"
super().__init__(message)
self.filename = filename
class FilePermissionsError(FileProcessingError):
"""Tekitatakse, kui rakendusel puuduvad piisavad õigused failile juurdepääsuks."""
def __init__(self, filename, message=None):
if message is None:
message = f"Ebapiisavad õigused failile juurdepääsuks: {filename}"
super().__init__(message)
self.filename = filename
class InvalidFileFormatError(FileProcessingError):
"""Tekitatakse, kui failil on kehtetu vorming (nt pole kehtiv CSV)."""
def __init__(self, filename, message=None):
if message is None:
message = f"Faili {filename} vorming on kehtetu"
super().__init__(message)
self.filename = filename
class DataProcessingError(FileProcessingError):
"""Tekitatakse, kui failisiseste andmete töötlemisel ilmneb viga."""
def __init__(self, filename, line_number, message):
super().__init__(message)
self.filename = filename
self.line_number = line_number
def process_file(filename):
try:
with open(filename, 'r') as f:
reader = csv.reader(f)
for i, row in enumerate(reader):
# Simuleerige andmetöötlusviga
if i == 5:
raise DataProcessingError(filename, i, "Vigased andmed real")
print(f"Töötlen rida: {row}")
except FileNotFoundError as e:
print(f"Viga: {e}")
except FilePermissionsError as e:
print(f"Viga: {e}")
except InvalidFileFormatError as e:
print(f"Viga: {e}")
except DataProcessingError as e:
print(f"Viga failis {e.filename}, real {e.line_number}: {e.message}")
except Exception as e:
print(f"Ilmnes ootamatu viga: {e}") #Kõikide ootamatute vigade püüdmiseks
# Näidiskasutus
import csv
# Simuleerige tĂĽhja CSV-faili loomist
with open('example.csv', 'w', newline='') as csvfile:
csvwriter = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
csvwriter.writerow(['Header 1', 'Header 2', 'Header 3'])
for i in range(10):
csvwriter.writerow([f'Data {i+1}A', f'Data {i+1}B', f'Data {i+1}C'])
process_file('example.csv')
process_file('nonexistent_file.csv') # Simuleerige FileNotFoundError
Selles näites oleme määratlenud erandite hierarhia tavaliste failitöötlusvigade käsitlemiseks. Funktsioon
process_file
näitab, kuidas neid erandeid püüda ja pakkuda informatiivseid veateateid. Kõikide vigade püüdmise
Exception
klausel on ülioluline ettenägematute vigade käsitlemiseks ja programmi kokkujooksmise vältimiseks. See lihtsustatud näide demonstreerib, kuidas kohandatud erindihierarhia suurendab teie koodi selgust ja robustsust.
Erinditöötlus globaalses kontekstis
Globaalsele sihtrühmale rakendusi arendades on oluline arvestada oma erinditöötluse strateegias kultuuriliste erinevuste ja keelebarjääridega. Siin on mõned kaalutlused:
- Lokaliseerimine: Veenduge, et veateated on lokaliseeritud kasutaja keelde. Kasutage tõlgitud veateadete pakkumiseks rahvusvahelistumise (i18n) ja lokaliseerimise (l10n) tehnikaid. Pythoni
gettextmoodul võib siin abiks olla. - Kuupäeva ja kellaaja vormingud: Olge veateadete kuvamisel teadlik erinevatest kuupäeva ja kellaaja vormingutest. Kasutage järjepidevat ja kultuuriliselt sobivat vormingut. Moodul
datetimepakub tööriistu kuupäevade ja kellaaegade vormindamiseks vastavalt erinevatele lokaatidele. - Arvuvormingud: Samamoodi olge teadlik erinevatest arvuvormingutest (nt komaeraldajad, tuhandete eraldajad), kui kuvate veateadetes numbrilisi väärtusi. Moodul
localeaitab teil vormindada numbreid vastavalt kasutaja lokaadile. - Märgikodeering: Käsitlege märgikodeeringu probleeme sujuvalt. Kasutage kogu rakenduses järjepidevalt UTF-8 kodeeringut, et toetada laia valikut märke.
- Valuutasümbolid: Rahaliste väärtustega tegelemisel kuvage vastavalt kasutaja lokaadile sobiv valuutasümbol ja -vorming.
- Õiguslikud ja regulatiivsed nõuded: Olge teadlik mis tahes õiguslikest või regulatiivsetest nõuetest, mis on seotud andmete privaatsuse ja turvalisusega erinevates riikides. Teie erinditöötlusloogika peab võib-olla vastama neile nõuetele. Näiteks Euroopa Liidu isikuandmete kaitse üldmäärusel (GDPR) on mõju sellele, kuidas te andmetega seotud vigu käsitlete ja nendest teatate.
Lokaliseerimise näide
gettext
'iga:
import gettext
import locale
import os
# Määrake lokaat
try:
locale.setlocale(locale.LC_ALL, '') # Kasutage kasutaja vaikimisi lokaati
except locale.Error as e:
print(f"Viga lokaadi määramisel: {e}")
# Määratlege tõlkedomeen
TRANSLATION_DOMAIN = 'myapp'
# Määrake tõlkekataloog
TRANSLATION_DIR = os.path.join(os.path.dirname(__file__), 'locales')
# Initsialiseerige gettext
translation = gettext.translation(TRANSLATION_DOMAIN, TRANSLATION_DIR, languages=[locale.getlocale()[0]])
translation.install()
_
class AuthenticationError(Exception):
def __init__(self, message):
super().__init__(message)
# Näidiskasutus
try:
# Simuleerige autentimise ebaõnnestumist
raise AuthenticationError(_("Vigane kasutajanimi või parool.")) # Allkriips (_) on gettext'i alias tõlkimiseks()
except AuthenticationError as e:
print(str(e))
See näide demonstreerib, kuidas kasutada
gettext
'i veateadete tõlkimiseks. Funktsiooni
_()
kasutatakse stringide märkimiseks tõlkimiseks. Seejärel loote iga toetatud keele jaoks tõlkefailid (nt kataloogis
locales
).
Täiustatud erinditöötluse tehnikad
Lisaks põhitõdedele on mitmeid täiustatud tehnikaid, mis võivad teie erinditöötluse strateegiat veelgi täiustada:
- Erandite aheldamine: Säilitage algne erand uue erandi tekitamisel. See võimaldab teil vea algpõhjust kergemini jälitada. Python 3-s saate erandite aheldamiseks kasutada süntaksit
raise ... from .... - Kontekstihaldurid: Kasutage kontekstihaldureid (lausendiga
with), et hallata ressursse automaatselt ja tagada puhastustoimingute tegemine, isegi kui tekivad erandid. - Erandite logimine: Integreerige erandite logimine robustse logimisraamistikuga (nt Pythoni sisseehitatud
loggingmoodul), et koguda üksikasjalikku teavet vigade kohta ja hõlbustada silumist. - AOP (Aspekt-orienteeritud programmeerimine): Kasutage AOP tehnikaid, et modulariseerida erinditöötlusloogikat ja rakendada seda järjepidevalt kogu oma rakenduses.
Kokkuvõte
Kohandatud erindihierarhiate kujundamine on võimas tehnika robustsete, hooldatavate ja informatiivsete Pythoni rakenduste loomiseks. Vigade hoolika kategoriseerimise, spetsiifiliste erindiklasside loomise ja kontekstuaalse teabe lisamisega saate oma koodi selgust ja vastupidavust oluliselt parandada. Ärge unustage järgida erinditöötluse parimaid praktikaid, arvestada oma rakenduse globaalse kontekstiga ja uurida täiustatud tehnikaid oma veatöötluse strateegia edasiseks täiustamiseks. Erinditöötluse valdamisega muutute vilunumaks ja tõhusamaks Pythoni arendajaks.